require 'channel'

module PCLink
  
  class Streamium
    def initialize
      @cached_nodes = {}
    end

    def connect(host, port)
      @channel = Channel.new({:host => host, :port => port})
    end

    def channel=(channel)
      @channel = channel
    end

    def albums(artist = nil)
      return list_category(:albums) unless artist
      
      @channel.list_node(artist.nodeid)
    end
    
    def artists
      artists = list_category(:artists)
      artists.each do |art|
        # create closure to retrieve albums listing for specific 
        # artist 
        list_albums_proc = lambda {@channel.list_node(art.nodeid)}
        
        # add attribute writer to node to assign the proc
        def art.list_albums_proc=(proc)
          @list_albums_proc = proc
        end
        
        # add method to list albums by invoking assigned proc
        def art.albums
          @list_albums_proc.call
        end
        
        # finally actally assign the proc
        art.list_albums_proc = list_albums_proc
      end
    end
    
    def list_node(id)
      @channel.list_node(id)
    end

    private 
    def list_category(category)
      category_node = cached_nodes(category)
      @channel.list_node(category_node.nodeid)
    end
    
    def cached_nodes(node_name)
      if !@cached_nodes.has_key?(node_name)
        load_node_data_into_cache(0)
      end
      return @cached_nodes[node_name] 
    end

    def load_node_data_into_cache(nodeid)
      @channel.list_node(nodeid).each do |node| 
        name = node.name.downcase.gsub('/ /', '_')
        @cached_nodes[name.to_sym] = node
      end
    end
  end
end